// #include <gl/glut.h>
// #include <cstdio>
// #include <math.h>
// 
// 
// const GLdouble PI = 3.141592;
// 
// 
// GLfloat xwcMin = -200.0, xwcMax = 250.0, ywcMin = -50.0, ywcMax = 250.0;
// //	GLsizei winWidth = xwcMax-xwcMin, winHeight = ywcMax-ywcMin;
// GLint	winWidth = 600, winHeight = 600;
// GLfloat x_0 = 100.0, y_0 = 50.0, z_0 = 50.0;
// GLfloat	xref = 50.0, yref = 50.0, zref = 0.0;
// GLfloat	Vx = 0.0, Vy = 1.0, Vz = 0.0;
// 
// GLfloat	xwMin = -40.0, ywMin = -60.0, xwMax = 40.0, yWMax = 60.0;
// GLfloat dnear = 25.0, dfar = 125.0;
// 
// class wcPt2D
// {
// public:
// 	GLfloat x, y;
// protected:
// private:
// };
// 
// 
// class wcPt3D
// {
// public:
// 	GLfloat x, y, z;
// protected:
// private:
// };
// 
// void rotate3D (wcPt3D p1, wcPt3D p2, GLfloat theta)
// {
// 	float vx = p2.x - p1.x;
// 	float vy = p2.y - p1.y;
// 	float vz = p2.z - p1.z;
// 
// 	// inverse order
// 	glTranslatef(p1.x, p1.y, p1.z);
// 	glRotatef(theta, vx, vy, vz);
// 	glTranslatef(-p1.x, -p1.y, -p1.z);
// }
// 
// 
// void scale3D (GLfloat sx, GLfloat sy, GLfloat sz, wcPt3D fixedPt)
// {
// 	// inverse order
// 	glTranslatef(fixedPt.x, fixedPt.y, fixedPt.z);
// 	glScalef(sx, sy, sz);
// 	glTranslatef(-fixedPt.x, -fixedPt.y, -fixedPt.z);
// }
// 
// 
// typedef GLfloat Matrix3x3 [3][3];
// 
// Matrix3x3 matComposite;
// 
// 
// 
// 
// static void init (void)
// {
// 	glClearColor(1.0, 1.0, 1.0, 0.0);
// 
// 	glMatrixMode(GL_MODELVIEW);
// 	gluLookAt(x_0, y_0, z_0, xref, yref, zref, Vx, Vy, Vz);
// 
// 	glMatrixMode(GL_PROJECTION);
// 	glFrustum(xwMin, xwMax, ywMin, yWMax, dnear, dfar);
// }
// 
// void matrix3x3SetIdentity (Matrix3x3 mat)
// {
// 	GLint row, col;
// 	for (row = 0; row < 3; row ++)
// 	{
// 		for (col = 0; col < 3; col++)
// 		{
// 			mat[row][col] = (row == col);
// 		}
// 	}
// }
// 
// // multiply m1m2 and save as m2
// void matrix3x3Multiply(Matrix3x3 mat1, Matrix3x3 mat2)
// {
// 	GLint row, col;
// 	Matrix3x3 mattemp;
// 
// 	for (row = 0; row < 3; row ++)
// 	{
// 		for (col = 0; col < 3; col++)
// 		{
// 			mattemp[row][col] = mat1[row][0]*mat2[0][col] + mat1[row][1]*mat2[1][col] + mat1[row][2]*mat2[2][col];
// 		}
// 	}
// 
// 
// 	for (row = 0; row < 3; row ++)
// 	{
// 		for (col = 0; col < 3; col++)
// 		{
// 			mat2[row][col] = mattemp[row][col];
// 		}
// 	}
// }
// 
// 
// void translate2D (GLfloat tx, GLfloat ty)
// {
// 	Matrix3x3 matTrans1;
// 
// 	matrix3x3SetIdentity(matTrans1);
// 
// 	matTrans1[0][2] = tx;
// 	matTrans1[1][2] = ty;
// 
// 	matrix3x3Multiply(matTrans1, matComposite);
// }
// 
// 
// void rotate2D (wcPt2D pivotPt, GLfloat theta)
// {
// 	Matrix3x3 matRot;
// 	
// 	matrix3x3SetIdentity(matRot);
// 
// 	matRot[0][0] = cos(theta);
// 	matRot[0][1] = -sin(theta);
// 	matRot[0][2] = pivotPt.x * (1 - cos(theta)) + pivotPt.y * sin(theta);
// 	
// 	matRot[1][0] = sin(theta);
// 	matRot[1][1] = cos(theta);
// 	matRot[1][2] = pivotPt.y * (1 - cos(theta)) - pivotPt.x * sin(theta);
// 
// 	matrix3x3Multiply(matRot, matComposite);
// }
// 
// 
// void scale2D (GLfloat sx, GLfloat sy, wcPt2D fixedPt)
// {
// 	Matrix3x3 matScale;
// 
// 	matrix3x3SetIdentity(matScale);
// 
// 	matScale[0][0] = sx;
// 	matScale[0][2] = fixedPt.x * (1 - sx);
// 
// 	matScale[1][1] = sy;
// 	matScale[1][2] = fixedPt.y * (1 - sx);
// 
// 	matrix3x3Multiply(matScale, matComposite);
// }
// 
// void transformVerts2D (GLint nVerts, wcPt2D * verts)
// {
// 	GLint k;
// 	GLfloat tempx, tempy;
// 
// 	for (k = 0; k < nVerts; k ++)
// 	{
// 		tempx = matComposite[0][0]*verts[k].x + matComposite[0][1]*verts[k].y + matComposite[0][2];
// 		tempy = matComposite[1][0]*verts[k].x + matComposite[1][1]*verts[k].y + matComposite[1][2];
// 
// 		verts[k].x = tempx;
// 		verts[k].y = tempy;
// 	}
// }
// 
// 
// void triangle (wcPt2D * verts)
// {
// 	GLint k;
// 
// 	glBegin(GL_TRIANGLES);
// 	{
// 		for (k = 0; k < 3; k++)
// 		{
// 			glVertex2f(verts[k].x, verts[k].y);
// 		}
// 	}
// 	glEnd();
// }
// 
// 
// 
// void displayFcn(void)
// {
// // 	GLint nVerts = 3;
// // 	wcPt2D verts[3] = { {50.0, 25.0}, {150.0, 25.0}, {100.0, 100.0} };
// // 
// // 	wcPt2D centroidPt;
// // 
// // 	GLint k, xSum = 0, ySum = 0;
// // 	for (k = 0; k < nVerts; k ++)
// // 	{
// // 		xSum += verts[k].x;
// // 		ySum += verts[k].y;
// // 	}
// // 	centroidPt.x = GLfloat(xSum) / GLfloat(nVerts);
// // 	centroidPt.y = GLfloat(ySum) / GLfloat(nVerts);
// // 
// // 	wcPt2D pivPt, fixedPt;
// // 	pivPt = centroidPt;
// // 	fixedPt = centroidPt;
// // 
// // 	GLfloat tx = 0.0, ty = 100.0, sx = 0.5, sy = 0.5;
// // 	GLdouble theta = PI/2.0;
// //
// // 	glClear(GL_COLOR_BUFFER_BIT);
// // 
// // 	glColor3f(0.0, 0.0, 1.0);
// // 	triangle(verts);
// // 
// // 
// // 
// // 
// // 	matrix3x3SetIdentity(matComposite);
// //  	scale2D(sx, sy, fixedPt);
// //  	rotate2D(pivPt, theta);
// //  	translate2D(tx, ty);
// // 
// // 	transformVerts2D(nVerts, verts);
// // 
// // 	glColor3f(1.0, 0.0, 0.0);
// // 	triangle(verts);
// // 
// // 
// // 
// // 
// // 	glFlush();
// // 
// // 	glMatrixMode(GL_MODELVIEW);
// // 
// // 	glClear(GL_COLOR_BUFFER_BIT);
// // 	glColor3f(0.0, 0.0, 1.0);
// // 	glRecti(50, 100, 200, 150);
// // 
// // 
// // 	glPushMatrix();
// // 	glColor3f(1.0, 0.0, 0.0);
// // 	glRotatef(90.0, 0.0, 0.0, 1.0);
// // 	glRecti(50, 100, 200, 150);
// // 	
// // 
// // 
// // 	glPopMatrix();
// // 	glTranslatef(-50.0, -100.0, 0.0);
// // 	glRecti(50, 100, 200, 150);
// // 
// // 	glFlush();
// // 	wcPt2D verts [3] = {{-50.0, -25.0}, {50.0, -25.0}, {0.0, 50.0}};
// // 
// // 	glClear(GL_COLOR_BUFFER_BIT);
// // 
// // 	glColor3f(0.0, 0.0, 1.0);
// // 	glViewport(0, 0, 300, 300);
// // 	triangle(verts);
// // 
// // 	glColor3f(1.0, 0.0, 0.0);
// // 	glViewport(300, 0, 300, 300);
// // 	glRotatef(90.0, 0.0, 0.0, 1.0);
// // 	triangle(verts);
// // 
// // 	glFlush();
// 	glClear(GL_COLOR_BUFFER_BIT);
// 
// 	glColor3f(0.0, 1.0, 0.0);
// 	glPolygonMode(GL_FRONT, GL_FILL);
// 	glPolygonMode(GL_BACK, GL_LINE);
// 	glBegin(GL_QUADS);
// 	{
// 		glVertex3f(0.0, 0.0, 0.0);
// 		glVertex3f(100.0, 0.0, 0.0);
// 		glVertex3f(100.0, 100.0, 0.0);
// 		glVertex3f(0.0, 100.0, 0.0);
// 	}
// 	glEnd();
// 
// 	glFlush();
// }
// 
// 
// 
// void winReshapeFnc (int newWidth, int newHeight)
// {
// 	glMatrixMode(GL_PROJECTION);
// 	glLoadIdentity();
// 
// 	gluOrtho2D(xwcMin, xwcMax, ywcMin, ywcMax);
// 
// 	glClear(GL_COLOR_BUFFER_BIT);
// }
// 
// void reshapeFcn(GLint newWidth, GLint newHeight)
// {
// 	glViewport(0, 0, newWidth, newHeight);
// 	winWidth = newWidth;
// 	winHeight = newHeight;
// }
// 
// 
// 
// void main (int argc, char** argv)
// {
// 	glutInit(&argc, argv);
// 	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
// 	glutInitWindowPosition(500, 100);
// 	glutInitWindowSize(winWidth, winHeight);
// 	glutCreateWindow("example");
// 
// 	init();
// 	glutDisplayFunc(displayFcn);
// 	glutReshapeFunc(reshapeFcn);
// 
// 	glutMainLoop();
// }
// 
